package io.esirong.net;

import android.util.Log;

import java.io.IOException;

import io.esirong.manager.AccessToken;
import io.esirong.manager.AccountManager;
import io.esirong.manager.login.LoginManager;
import okhttp3.Authenticator;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Route;

/**
 * OAuthInterceptor
 *
 * @author 黄嵘才
 * @date 2017/7/10
 */
public final class OAuthInterceptor {

    private static final String TAG = "OAuthInterceptor";

    /**
     * 访问令牌(accessToken)处理(检查，设置，更新，保存)
     *
     * @return Interceptor
     */
    public static Interceptor tokenInterceptor() {
        return tokenInterceptor;
    }

    /**
     * 访问令牌(accessToken)授权失效处理
     *
     * @return Authenticator
     */
    public static Authenticator authenticator() {
        return authenticator;
    }

    /**
     * 访问令牌(token)处理(检查，设置，更新，保存)
     */
    private static Interceptor tokenInterceptor = new Interceptor() {
        private static final String HEADER_ACCESS_TOKEN = "accessToken";

        @Override
        public Response intercept(Chain chain) throws IOException {

            AccessToken oauthToken = AccountManager.getAccessToken();
            //find the token
            String token = "";
            String refreshToken = "";
            if (oauthToken != null) {
                token = oauthToken.getToken();
                refreshToken = oauthToken.getRefreshToken();
            }
            //add it to the request
            Request.Builder builder = chain.request().newBuilder();
            if (!token.isEmpty()) {
                Log.e(TAG, "In the interceptor adding the header authorization with : " + token);
                builder.header(HEADER_ACCESS_TOKEN, token);
            } else {
                Log.e(TAG, "In the interceptor there is a fuck with : " + token);
                //you should launch the loginActivity to fix that:
                LoginManager.launchLogin();
            }
            //proceed to the call
            Response originalResponse = chain.proceed(builder.build());
            //尝试更新访问口令
            String access = originalResponse.header(HEADER_ACCESS_TOKEN);
            if (access != null && !access.isEmpty() && !refreshToken.isEmpty()) {
                AccessToken accessToken = new AccessToken(access, refreshToken, 0L);
                if (!accessToken.equals(oauthToken)) {
                    AccountManager.saveAccount(accessToken);
                }
            }
            //add it to the Response
            return originalResponse.newBuilder()
                    .build();
        }
    };

    /**
     * 登录令牌(token)授权失效处理
     */
    private static Authenticator authenticator = new Authenticator() {
        private static final String REFRESH_TOKEN = "refreshToken";

        @Override
        public Request authenticate(Route route, Response response) throws IOException {
            //通过请求头附带刷新Token 使服务重新授权口令
            String refresh = "";
            if (AccountManager.getAccessToken() != null) {
                refresh = AccountManager.getAccessToken().getRefreshToken();
            }
            if (refresh.isEmpty()) {
                return null;
            }
            if (refresh.equals(response.request().header(REFRESH_TOKEN))) {
                Log.e(TAG, "already failed with these credentials, don't retry");
                //you should launch the loginActivity to fix that:
                handleAuthenticateResponse(response);
                return null; // If we already failed with these credentials, don't retry.
            }
            Log.d(TAG, "refresh token with the refreshToken ");
            return response.request().newBuilder()
                    .header(REFRESH_TOKEN, refresh)
                    .build();

            /*//通过请求头附带刷新Token 使服务重新授权口令
            String credential = Credentials.basic("jesse", "password");
            if (credential.equals(response.request().header("Authorization"))) {
                return null; // If we already failed with these credentials, don't retry.
            }
            return response.request().newBuilder()
                    .header("Authorization", credential)
                    .build();*/
        }

    };

    private static void handleAuthenticateResponse(Response response) {
        onAuthenticateRefreshFailed(response);
    }

    private static void onAuthenticateRefreshFailed(Response response) {
        LoginManager.handleFailed(response.message());

    }


}
